#include "fifo.h"

FIFO_HANDLE FIFO_Init()
{
	struct list_head *plisthead = NULL;
	FIFO_HANDLE ThisFifo;
	
    ThisFifo = (FIFO_HANDLE)malloc(sizeof(struct hiFIFO_HANDLE));
	if(NULL == ThisFifo)
	{
		return NULL;
	}
	
	plisthead = (struct list_head *)malloc(sizeof(struct list_head));
	if(NULL == plisthead)
	{
		return NULL;
	}

	INIT_LIST_HEAD(plisthead);
	
	ThisFifo->list_head = plisthead;
	InitializeCriticalSection(&ThisFifo->Fifo_Section);
	
	return ThisFifo;
}


BOOL FIFO_Put(FIFO_HANDLE Handle, DMAPacket *pData)
{
	struct list_head *plisthead;

	if((NULL == Handle) || (NULL == pData) || (NULL == Handle->list_head))
	{
		return FALSE;
	}


	EnterCriticalSection(&Handle->Fifo_Section);
	plisthead = (struct list_head *)Handle->list_head;		
	list_add(&pData->list, plisthead);
	LeaveCriticalSection(&Handle->Fifo_Section);
	return TRUE;
}


DMAPacket * FIFO_Get(FIFO_HANDLE Handle)
{
	struct list_head *plisthead;
	struct list_head *plist;
	DMAPacket * pData;  

	if((NULL == Handle) || (NULL == Handle->list_head))
	{
		return NULL;
	}

	EnterCriticalSection(&Handle->Fifo_Section);
	plisthead = (struct list_head *)Handle->list_head;
	if(list_empty(plisthead))
	{
	    LeaveCriticalSection(&Handle->Fifo_Section);
		return NULL;
	}

	plist = plisthead->prev;	  		  
	pData = list_entry(plist ,DMAPacket, list);

	list_del(plist);
	LeaveCriticalSection(&Handle->Fifo_Section);
	
	return pData;
}



BOOL FIFO_DeInit(FIFO_HANDLE Handle)
{
	if(NULL == Handle)
	{
		return FALSE;
	}

    DeleteCriticalSection(&Handle->Fifo_Section);
    free(Handle->list_head);
	free(Handle);
	Handle = NULL;
	return TRUE;
}


